home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / minix / mdbtar~1.z / mdbtar~1 / mdbdis.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  7.9 KB  |  430 lines

  1. /*
  2.  * mdbdis.c - MINIX program disassembler
  3.  *
  4.  * Written by Bruce D. Szablak
  5.  *
  6.  * This free software is provided for non-commerical use. No warrantee
  7.  * of fitness for any use is implied. You get what you pay for. Anyone
  8.  * may make modifications and distribute them, but please keep this header
  9.  * in the distribution.
  10.  */
  11.  
  12. #include <stdio.h>
  13.  
  14. #define BYTE 0
  15. #define WORD 1
  16. #define LONG 2
  17.  
  18. #define BFIELD(w,b,l) (((w) >> ((b)-(l)+1)) & (int)((1L<<(l))-1))
  19. #define BTST(w,b) ((w) & (1 << (b)))
  20. char opwfmt[] = "%s.%c\t";
  21. #define OPI(s,w) printf(opwfmt, s, w)
  22.  
  23. char size[] = "bwl";
  24. char *cc[] = {"ra", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs",
  25.     "pl", "mi", "ge", "lt", "gt", "le" };
  26.  
  27. char *bitop[] = { "btst", "bchg", "bclr", "bset" };
  28. char *imedop[] = { "ori", "andi", "subi", "addi", "?", "eori", "cmpi" };
  29. char *misc1[] = { "negx", "clr", "neg", "not" };
  30. char *misc2[] = { "reset", "nop", "stop", "rte", "??", "rts", "trapv", "rtr" };
  31. char *shf[] = { "as", "ls", "rox", "ro" };
  32.  
  33. char *fmts[] = { "d%d", "a%d", "(a%d)", "(a%d)+", "-(a%d)" };
  34.  
  35. extern curpid;
  36. extern char *addr_to_name();
  37. extern long saddr, eaddr;
  38.  
  39. long gaddr, gbuf, ptrace();
  40. int gempty, gisize, gjmp;
  41.  
  42. short
  43. gword()
  44. {
  45.     if (gempty)
  46.     {
  47.         gempty = 0;
  48.         gbuf = ptrace(1, curpid, gaddr, 0L);
  49.         gaddr += 2;
  50.         return gbuf >> 16;
  51.     }
  52.     gempty = 1;
  53.     gaddr += 2;
  54.     return gbuf;
  55. }
  56.  
  57. long
  58. glong()
  59. {
  60.     gempty = 1;
  61.     gbuf = ptrace(1, curpid, gaddr, 0L);
  62.     gaddr += 4;
  63.     return gbuf;
  64. }
  65.  
  66. reladdr(sep)
  67.     char sep;
  68. {
  69.     int d = gword();
  70.     symbolic(gaddr + d - 2, sep);
  71. }
  72.  
  73. movem(from, predec, rmsk)
  74. {
  75.     int b, f = 0;
  76.  
  77.     if (!from) putc(',', stdout);
  78.     for (b = 16; b--; rmsk >>= 1)
  79.     {
  80.         if (rmsk & 1)
  81.         {
  82.             if (f) putc('/', stdout);
  83.             else f = 1;
  84.             if (predec) printf("%c%d", b>7 ? 'a' : 'd', b % 8);
  85.             else printf("%c%d", b>7 ? 'd' : 'a', 7 - b % 8);
  86.         }
  87.     }
  88.     if (from) putc(',', stdout);
  89. }
  90.  
  91. op1(mode,reg)
  92. {
  93.     int    d;
  94.     char    *s;
  95.     long    l;
  96.  
  97.     if (mode < 5)
  98.     {
  99.         printf(fmts[mode], reg);
  100.         return;
  101.     }
  102.     if (mode == 5)
  103.     {
  104.         printf("%d(a%d)", gword(), reg);
  105.         return;
  106.     }
  107.     if (mode == 6)
  108.     {
  109.         d = gword();
  110.         printf("%d(a%d,%c%d.%c)",
  111.             BFIELD(d,7,8) | (BTST(d,7) ? 0xFF00 : 0), reg,
  112.             BTST(d,15) ? 'a' : 'd', BFIELD(d,14,3),
  113.             BTST(d,11) ? 'l' : 'w');
  114.         return;
  115.     }
  116.     switch (reg)
  117.     {
  118.     case 0:    printf("%d.w", gword()); break;
  119.     case 1:    symbolic(glong(), '\0'); break;
  120.     case 2: l = gaddr;
  121.         printf("%d(pc) {", d = gword());
  122.         symbolic(l+d, '}');
  123.         break;
  124.     case 3: d = gword();
  125.         printf("%d(pc,%c%d.%c)",
  126.             BFIELD(d,7,8) | (BTST(d,7) ? 0xFF00 : 0),
  127.             BTST(d,15) ? 'a' : 'd', BFIELD(d,14,3),
  128.             BTST(d,11) ? 'l' : 'w');
  129.         break;
  130.     case 4: putc('#', stdout);
  131.         if (gisize == LONG) symbolic(glong(), '\0');
  132.         else if (gisize == BYTE) printf("%d", (char)gword());
  133.         else printf("%d", gword());
  134.         break;
  135.     case 5: printf("sr"); break;
  136.     }
  137. }
  138.  
  139. op2(f,m1,r1,m2,r2) /* f set means order passed, clear reverses order */
  140. {
  141.     if (f) op1(m1,r1); else op1(m2,r2);
  142.     putc(',',stdout);
  143.     if (f) op1(m2,r2); else op1(m1,r1);
  144. }
  145.  
  146. opmode(op, opm, reg, m, r)
  147.     char *op;
  148. {
  149.     OPI(op, size[gisize=BFIELD(opm,1,2)]);
  150.     op2(BTST(opm,2),0,reg,m,r);
  151. }
  152.  
  153. long
  154. dasm(addr,cnt, symflg)
  155.     long addr;
  156. {
  157.     int    tflg = 0;
  158.     register unsigned int w, m1, m2, r1, r2, op;
  159.     char     ds;
  160.  
  161.     gaddr = addr; gempty = 1;
  162.     while (tflg || cnt--)
  163.     {
  164.         tflg = 0;
  165.         if (symflg) symbolic(gaddr, '\t');
  166.         else printf("0x%lx ", gaddr);
  167.         w = gword();
  168.         m1 = BFIELD(w,8,3); m2 = BFIELD(w,5,3);
  169.         r1 = BFIELD(w,11,3); r2 = BFIELD(w,2,3);
  170.         op = BFIELD(w,15,4);
  171.         switch (op)
  172.         {
  173.         case 0x0:
  174.             if (m2 == 1)
  175.             {
  176.                 OPI("movep", BTST(w,6) ? 'l' : 'w');
  177.                 op2(BTST(w,7),0,r1,5,r2);
  178.                 break;
  179.             }
  180.             if (BTST(w,8))
  181.             {
  182.                 OPI(bitop[BFIELD(w,7,2)], m2 ? 'b' : 'l');
  183.                 op2(1,0,r1,m2,r2);
  184.                 break;
  185.             }
  186.             if (r1 == 4)
  187.             {
  188.                 OPI(bitop[BFIELD(w,7,2)], m2 ? 'b' : 'l');
  189.                 gisize = WORD;
  190.                 op2(1,7,4,m2,r2);
  191.                 break;
  192.             }
  193.             OPI(imedop[r1],size[gisize = m1]);
  194.             op2(1,7,4,m2,r2);
  195.             break;
  196.         case 0x1:
  197.             gisize = BYTE; goto domove;
  198.         case 0x2:
  199.             gisize = LONG; goto domove;
  200.         case 0x3:
  201.             gisize = WORD;
  202.  
  203.             domove:
  204.                 OPI("move", size[gisize]);
  205.                 op2(1,m2,r2,m1,r1);
  206.             break;
  207.         case 0x4:
  208.             if (BTST(w,8))
  209.             {
  210.                 if (BTST(w,6))
  211.                 {
  212.                     printf("lea\t");
  213.                     op1(m2,r2);
  214.                     printf(",a%d", r1);
  215.                     break;
  216.                 }
  217.                 printf("chk\t");
  218.                 op1(m2,r2);
  219.                 printf(",d%d", r1);
  220.                 break;
  221.             }
  222.             if (r1 < 4)
  223.             {
  224.                 if (m1 == 3)
  225.                 {
  226.                     printf("move\t");
  227.                     gisize = WORD;
  228.                     if (r1 == 0) printf("sr,");
  229.                     op1(m2,r2);
  230.                     if (r1 == 2) printf(",ccr");
  231.                     if (r1 == 3) printf(",sr");
  232.                     break;
  233.                 }
  234.                 OPI(misc1[r1], size[m1]);
  235.                 op1(m2,r2);
  236.                 break;
  237.             }
  238.             else if (r1 == 4)
  239.             {
  240.                 switch(m1)
  241.                 {
  242.                 case 0: printf("nbcd\t"); break;
  243.                 case 1: printf(m2 ? "pea\t" : "swap\t"); break;
  244.                 case 2:
  245.                 case 3:    OPI(m2 ? "movem" : "ext",
  246.                         BTST(w,6) ? 'l' : 'w');
  247.                     if (m2) movem(1,m2==4, gword());
  248.                     break;
  249.                 }
  250.                 op1(m2,r2);
  251.                 break;
  252.             }
  253.             if (r1 == 5)
  254.             {
  255.                 if (m1 == 3) printf("tas\t");
  256.                 else OPI("tst", size[m1]);
  257.                 op1(m2,r2);
  258.                 break;
  259.             }
  260.             if (r1 == 6)
  261.             {
  262.                 OPI("movem", BTST(w,6) ? 'l' : 'w');
  263.                 op = gword();
  264.                 op1(m2,r2);
  265.                 movem(0,m2==4,op);
  266.                 break;
  267.             }
  268.             if (BTST(w,7))
  269.             {
  270.                 printf(BTST(w,6) ? "jmp\t" : "jsr\t");
  271.                 op1(m2,r2);
  272.                 break;
  273.             }
  274.             switch (m2)
  275.             {
  276.             case 0:
  277.             case 1:    printf("trap\t#%d", BFIELD(w,3,4));
  278.                 tflg = 1;
  279.                 break;
  280.             case 2: printf("link\ta%d,#%d", r2, gword()); break;
  281.             case 3: printf("unlk\ta%d", r2); break;
  282.             case 4: printf("move.l a%d,usp", r2); break;
  283.             case 5: printf("move.l usp,a%d", r2); break;
  284.             case 6: printf(misc2[r2]); break;
  285.             }
  286.             break;
  287.         case 0x5:
  288.             if (BFIELD(w,7,2) == 3)
  289.             {
  290.                 op = BFIELD(w,11,4);
  291.                 if (m2 == 1)
  292.                 {
  293.                     printf("db%s\td%d,",cc[op], r2);
  294.                     reladdr('\0');
  295.                 }
  296.                 else
  297.                 {
  298.                     printf("s%s\t",cc[op]);
  299.                     op1(m2,r2);
  300.                 }
  301.             }
  302.             else
  303.             {
  304.                 printf("%sq.%c\t#%d,",BTST(w,8)?"sub":"add",
  305.                     size[BFIELD(w,7,2)],
  306.                     ((r1 - 1) & 7) + 1);
  307.                 op1(m2,r2);
  308.             }
  309.             break;
  310.         case 0x6:
  311.             ds = BFIELD(w,7,8);
  312.             printf("b%s.%c\t", cc[BFIELD(w,11,4)], ds ? 's' : 'w');
  313.             if (ds) symbolic(gaddr+ds,'\0');
  314.             else reladdr('\0');
  315.             break;
  316.         case 0x7:
  317.             printf("moveq\t#%d,d%d",BFIELD(w,7,8),r1);
  318.             break;
  319.         case 0x8:
  320.             if (m1 == 3 || m1 == 7)
  321.             {
  322.                 printf("div%c\t", BTST(w,8) ? 's' : 'u');
  323.                 op2(0,0,r1,m2,r2);
  324.             }
  325.             else if (m1 == 4 && (m2 == 1 || m2 == 0))
  326.             {
  327.                 printf(m2 ? "sbcd\t-(a%d),-(a%d)"
  328.                       : "sbcd\td%d,d%d", r2, r1);
  329.             }
  330.             else
  331.             {
  332.                 opmode("or",m1,r1,m2,r2);
  333.             }
  334.             break;
  335.         case 0x9:
  336.         case 0xD:
  337.             if ((m2 == 0 || m2 == 1) && m1 > 3 && m1 < 7)
  338.             {
  339.                 OPI(op == 9 ? "subx" : "addx",
  340.                     size[BFIELD(w,7,2)]);
  341.                 m2 <<= 2;
  342.                 op2(1,m2,r2,m2,r1);
  343.             }
  344.             else if (m1 == 3 || m1 == 7)
  345.             {
  346.                 gisize = m1 == 3 ? WORD : LONG;
  347.                 OPI(op==9 ? "sub" : "add", size[gisize]);
  348.                 op2(1,m2,r2,1,r1);
  349.             }
  350.             else
  351.             {
  352.                 opmode(op==9 ? "sub" : "add",m1,r1,m2,r2);
  353.             }
  354.             break;
  355.         case 0xB:
  356.             if (BTST(w,8))
  357.             {
  358.                 if (m2 == 1)
  359.                 {
  360.                     OPI("cmpm", size[BFIELD(w,7,2)]);
  361.                     printf("(a%d)+,(a%d)+",r2,r1);
  362.                 }
  363.                 else
  364.                 {
  365.                     opmode("eor",m1,r1,m2,r2);
  366.                 }
  367.             }
  368.             else
  369.             {
  370.                 opmode("cmp",m1,r1,m2,r2);
  371.             }
  372.             break;
  373.         case 0xC:
  374.             if (m1 == 3 || m1 == 7)
  375.             {
  376.                 printf("mul%c\t", m1==7 ? 's' : 'u');
  377.                 op2(0,0,r1,m2,r2);
  378.             }
  379.             else if (m1 == 4 && (m2 == 1 || m2 == 0))
  380.             {
  381.                 printf(m2 ? "abcd\t-(a%d),-(a%d)"
  382.                       : "abcd\td%d,d%d", r2, r1);
  383.             }
  384.             else if (m1 == 5)
  385.             {
  386.                 op = BTST(w,3) ? 'a' : 'd';
  387.                 printf("exg\t%c%d,%c%d",op,r1,op,r2);
  388.             }
  389.             else if (m1 == 6)
  390.             {
  391.                 printf("exg\td%d,a%d",r1,r2);
  392.             }
  393.             else
  394.             {
  395.                 opmode("and",m1,r1,m2,r2);
  396.             }
  397.             break;
  398.         case 0xE:
  399.             if (BFIELD(w,7,2) == 3)
  400.             {
  401.                 printf("%s%c.w\t",shf[BFIELD(w,10,2)],
  402.                     BTST(w,8) ? 'l' : 'r');
  403.                 op1(m2,r2);
  404.             }
  405.             else
  406.             {
  407.                 printf("%s%c.%c\t",shf[BFIELD(w,4,2)],
  408.                     BTST(w,8) ? 'l' : 'r',
  409.                     size[BFIELD(w,7,2)]);
  410.                 if (BTST(w,5))
  411.                 {
  412.                     op2(1,0,r1,0,r2);
  413.                 }
  414.                 else
  415.                 {
  416.                     printf("#%d,",r1);
  417.                     op1(0,r2);
  418.                 }
  419.             }
  420.             break;
  421.         case 0xA:
  422.         case 0xF:
  423.             printf("%x", w);
  424.             break;
  425.         }
  426.         putc('\n',stdout);
  427.     }
  428.     return gaddr;
  429. }
  430.